View Javadoc
1 /************************************************************ 2 * Copyright * 3 * Portions of this software are Copyright (c) 1993 - 2002, * 4 * Chad Z. Hower (Kudzu) and the Indy Pit Crew * 5 * - http://www.nevrona.com/Indy/ * 6 ************************************************************/ 7 package org.indy.util; 8 9 import java.io.ByteArrayInputStream; 10 import java.io.ByteArrayOutputStream; 11 import java.io.IOException; 12 13 14 /*** 15 * A light weight read-write buffer used by Indy. 16 * 17 * NOTE: This class is not thread-safe; if you wish to use 18 * this IdBuffer in a multi-threaded environment you must 19 * provide your own synchronization. 20 * 21 *@author OTG 22 *@version 1.0 23 */ 24 public class IndyBuffer extends ByteArrayOutputStream { 25 private OpenByteArrayInputStream reader = new OpenByteArrayInputStream(buf, 0, 26 buf.length); 27 28 /*** 29 * Checks whether reader's buffer is in sync with writer's, 30 * and refreshes if neccessary. 31 */ 32 protected void readerIsDirty() { 33 //could be that the whole buffer reference has changed, 34 //or just that the count needs updating 35 if (reader.getBufLength() != buf.length) { 36 //something of a hack 37 reader = new OpenByteArrayInputStream(buf, reader.getPos(), 38 count - reader.getPos()); 39 } 40 else if (count != reader.getCount()) { 41 reader.setCount(count); 42 } 43 } 44 45 /*** 46 * Clears the buffer 47 */ 48 public void clear() { 49 reset(); 50 reader.reset(); 51 } 52 53 /*** 54 * Returns some data from the buffer non-destructively 55 * (i.e. doesn't remove it). 56 * 57 *@param b An array of bytes to read into 58 *@param off The offset to start filling <code>b</code> at 59 *@param len The number of bytes to read 60 *@throws IndexOutOfBoundsException If off or len are invalid 61 *@see #read(byte[],int,int) 62 */ 63 public void peek(byte[] b, int off, int len) { 64 if ((off < 0) || (off > count) || (len < 0) || ((off + len) > count) || 65 ((off + len) < 0)) { 66 throw new IndexOutOfBoundsException(); 67 } 68 69 System.arraycopy(buf, off, b, 0, len); 70 } 71 72 /*** 73 * Reads some bytes from the buffer. 74 * 75 *@param b An array of bytes to read into. 76 *@param off The offset to start filling <code>b</code> at 77 *@param len The number of bytes to read 78 *@see #peek(byte[],int,int) 79 */ 80 public void read(byte[] b, int off, int len) { 81 readerIsDirty(); 82 83 84 /*** @todo Bounds checking here */ 85 reader.read(b, off, len); 86 } 87 88 /*** 89 * Attempts to read a line of text from the buffer. See 90 * the general contract of {@Link OpenByteArryInputStream#readLine()}. 91 * 92 *@return A line of text from the buffer, or null if no line is found. 93 *@throws IOException If an IO error occurrs. 94 */ 95 public String readLine() throws IOException { 96 readerIsDirty(); 97 98 return reader.readLine(); 99 } 100 101 /*** 102 * Returns the current number of bytes in the buffer. 103 * 104 * @return The current size of the buffer in bytes. 105 */ 106 public int size() { 107 readerIsDirty(); 108 109 return count - reader.getPos(); 110 } 111 112 /*** 113 * A ByteArrayInputStream that exposes it's current 114 * position so it can be synced with the overall buffer. 115 * 116 *@author OTG 117 */ 118 private class OpenByteArrayInputStream extends ByteArrayInputStream { 119 /*** 120 * Constructs a new instance. 121 * 122 *@param b The buffer to use. 123 *@param offset The offset at which to start reads. 124 *@param len The length of the buffer. 125 */ 126 public OpenByteArrayInputStream(byte[] b, int offset, int len) { 127 super(b, offset, len); 128 } 129 130 private void setCount(int newCount) { 131 super.count = newCount; 132 } 133 134 /*** 135 * Gets the current read position 136 * 137 *@return The read position of the buffer. 138 */ 139 public int getPos() { 140 return this.pos; 141 } 142 143 /*** 144 * Gets the current length of the buffer array. 145 * 146 *@return The length of the buffer array. 147 */ 148 public int getBufLength() { 149 return super.buf.length; 150 151 //make *positive* we're getting the right one! 152 } 153 154 /*** 155 * Gets the current amount of buffered data. 156 * 157 *@return The amount of buffered data in bytes. 158 */ 159 public int getCount() { 160 return super.count; 161 } 162 163 byte[] peek() { 164 byte[] res = new byte[this.count]; 165 166 System.arraycopy(super.buf, 0, res, 0, this.count); 167 168 return res; 169 } 170 171 /*** 172 * Reads a line of character data from the buffer. 173 * This, unlike java.io.BufferedReader will return 174 * null if there is data, but no EOL. 175 * 176 * It allows any combination of LF and CR. 177 * 178 *@return A line of text, or NULL if no EOL is present. 179 *@throws IOException If an IO error occurs. 180 */ 181 public String readLine() throws IOException { 182 byte[] b = new byte[count - pos]; 183 184 System.arraycopy(buf, pos, b, 0, count - pos); 185 186 String s = new String(b); 187 char[] c = s.toCharArray(); 188 189 boolean pairedBreak = false; 190 int cpos = 0; 191 192 for (int i = 0; i < c.length; i++) { 193 if ((c[i] == '\n') || (c[i] == '\r')) { 194 cpos = i; 195 196 if ((i + 1) < c.length) { 197 if ((c[i + 1] == '\n') || (c[i + 1] == '\r')) { 198 pairedBreak = true; 199 } 200 } 201 202 break; 203 } 204 } 205 206 String res = null; 207 208 if (cpos > 0) { 209 pos += (s.substring(0, cpos).getBytes().length + 1); 210 res = s.substring(0, cpos); 211 } 212 213 //get rid of the feed chars 214 if (pairedBreak) { 215 pos++; 216 } 217 218 return res; 219 } 220 } 221 }

This page was automatically generated by Maven